library motion 
    globals
        private real epsilon = 0.0001
    endglobals

    //贝塞尔曲线公式
    function curveX takes real x1, real x2, real t returns real 
        return 3*x1*t*(1 - t)*(1 - t) + 3*x2*t*t*(1 - t) + t*t*t
    endfunction

    //贝塞尔曲线的导数
    function derivativeCurveX takes real x1, real x2, real t returns real 
        return 3*x1*(1 - t)*(1 - t) - 6*x1*t*(1 - t) + 6*x2*t*(1 - t) - 3*x2*t*t + 3*t*t
    endfunction

    //贝塞尔曲线的导数，与上方函数相同
    function derivativeCurveX2 takes real x1, real x2, real t returns real 
        return 3*x1 - 12*x1*t + 9*x1*t*t + 6*x2*t - 9*x2*t*t + 3*t*t
    endfunction
    
    function curveY takes real y1, real y2, real t returns real 
        return 3*y1*t*(1 - t)*(1 - t) + 3*y2*t*t*(1 - t) + t*t*t
    endfunction

    // 贝塞尔曲线动画函数
    function RCubicBezier takes real x1, real y1, real x2, real y2, real t returns real 
        local real x3 = 0
        local real t0 = 0
        local real t1 = 1
        local real t2 = 0
        local integer i = 0
        local real d2 = 0
        
        set t2 = t
        if (t2 < t0) then
            return 0
        endif
        if (t2 > t1) then
            return 1
        endif
        // First try a few iterations of Newton's method -- normally very fast.
        // 首先尝试几次牛顿法迭代 -- 通常非常快
        loop
            exitwhen i>=8
            set x3 = curveX(x1,x2,t2) - t
            if (RAbsBJ(x3) < epsilon) then // 误差值在容忍范围内
                //call DisplayTextToPlayer(Player(0), 0, 0, I2S(i))
                return curveY(y1,y2,t2)
            endif
            set d2 = derivativeCurveX2(x1,x2,t2)
            exitwhen RAbsBJ(d2) < 0.0000001  // 出现导数为0的情况时退出循环
            set t2 = t2 - x3 / d2
            set i = i + 1
        endloop

        //如果牛顿迭代法没有结果就使用二分法逼近
        set t2 = t
        loop
            exitwhen t0>=t1
            set x3 = curveX(x1,x2,t2)
            if (RAbsBJ(x3 - t) < epsilon) then
                return curveY(y1,y2,t2)
            endif
            if (t > x3) then
                set t0 = t2
            else 
               set t1 = t2 
            endif
            set t2 = (t1 - t0) * 0.5 + t0
        endloop
        return curveY(y1,y2,t0)
    endfunction

endlibrary